package com.mc.common.redis;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.exceptions.JedisConnectionException;

import javax.annotation.PostConstruct;

@PropertySource(value = "redis.properties")
@Component
public class JedisBuilder {

	private JedisPool jedisPool;

	//密码 可以为空
	@Value(value = "${redis.password}")
	private String password;

	//ip地址
	@Value(value = "${redis.host}")
	private String host;

	//端口号
	@Value(value = "${redis.port}")
	private int port;

	//超时时间
	@Value(value = "${redis.connectionTimeout}")
	private int timeout;

	//连接重试次数
	@Value(value = "${redis.failTimes}")
	private int failTimes;

	//value最大值
	@Value(value = "${redis.max.value.size}")
	private long maxValueSize;

	private static final int DEFAULT_TIMEOUT = 2000;//连接超时时间
	private static final int DEFAULT_MAX_RETRY = 5;//连接重试次数

	/**
	 * 初始化 加载redis连接池
	 */
	@PostConstruct
	public void initBean() {

		GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig();
		genericObjectPoolConfig.setMaxIdle(20);
		genericObjectPoolConfig.setMaxTotal(-1);
		genericObjectPoolConfig.setMaxWaitMillis(5000);
		genericObjectPoolConfig.setTestOnBorrow(false);

		timeout = timeout <= 0 ? DEFAULT_TIMEOUT : timeout;

		if (StringUtils.isNotBlank(password)) {
			jedisPool = new JedisPool(genericObjectPoolConfig, host, port, timeout, password);
		} else {
			jedisPool = new JedisPool(genericObjectPoolConfig, host, port, timeout);
		}
	}

	/**
	 * 获取value值最大限制
	 *
	 * @return
	 */
	public long getMaxValueSize() {
		return this.maxValueSize;
	}

	/**
	 * 从池中拿到连接
	 *
	 * @return
	 */
	public Jedis getJedis() {
		int timeoutCount = 0;
		while (true) {
			try {
				return jedisPool.getResource();
			} catch (Exception e) {
				if (e instanceof JedisConnectionException) {
					timeoutCount++;
					failTimes = failTimes <= 0 ? DEFAULT_MAX_RETRY : failTimes;
					if (timeoutCount > failTimes) {
						break;
					}
				} else {
					System.out.println("当前连接池信息:numActive=" + jedisPool.getNumActive() + ", numIdle=" + jedisPool.getNumIdle() +
							", numWaiters=" + jedisPool.getNumWaiters() + ", isClosed=" + jedisPool.isClosed());

					break;
				}
			}
		}
		return null;
	}

}
